package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"
)

// var gitStatusCmdOptions = []string{"status", "--porcelain"}
var gitDiffCmdOptions = []string{"diff", "--name-only", "HEAD"}
var fixjsstyleCmdOptions = []string{"--strict"}

const gitCmd = "git"
const fixjsstyleCmd = "fixjsstyle"
const modified = "M"

func main() {
	fmt.Printf("Formatting uncommitted files...\n")

	// Find git in path.
	gitPath, err := exec.LookPath(gitCmd)
	if err != nil {
		log.Fatal("git not found!")
	}

	currentDir, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	currentDirList := strings.Split(currentDir, string(os.PathSeparator))

	// Get the files that were modified (uncommitted).
	out, err := exec.Command(gitPath, gitDiffCmdOptions...).Output()
	if err != nil {
		log.Fatal(err)
	}

	linesOut := strings.Split(string(out[:]), "\n")

	var modifiedFiles []string
	for _, line := range linesOut {
		// fields := strings.Fields(line)
		//
		// if len(fields) == 0 {
		// 	continue
		// }
		//
		// if strings.Contains(fields[0], modified) {
		// 	modifiedFiles = append(modifiedFiles, normalizePath(currentDirList, fields[len(fields)-1]))
		// }

		if line != "" {
			modifiedFiles = append(modifiedFiles, normalizePath(currentDirList, line))
		}
	}

	// fmt.Printf("modifiedFiles: %q\n", modifiedFiles)

	// Run "fixjsstyle --strict" on every file.
	for _, modifiedFile := range modifiedFiles {
		ops := make([]string, 1)
		copy(ops, fixjsstyleCmdOptions)
		ops = append(ops, modifiedFile)

		out, err := exec.Command(fixjsstyleCmd, ops...).Output()
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(string(out[:]))
	}
}

func normalizePath(base []string, filePath string) string {
	pathElems := strings.Split(filePath, string(os.PathSeparator))

	pathStart := 0
	lastBase := base[len(base)-1]
	for i, dir := range pathElems {
		if dir == lastBase {
			// Verify that the previous base path elements match the rest of path.
			allMatch := true
			for j := 0; j <= i; j++ {
				if base[len(base)-(1+j)] != pathElems[i-j] {
					allMatch = false
				}
			}

			if allMatch {
				pathStart = i + 1
				break
			}
		}
	}

	return strings.Join(pathElems[pathStart:], string(os.PathSeparator))
}
